/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controladoresJpa;

import controladoresJpa.exceptions.IllegalOrphanException;
import controladoresJpa.exceptions.NonexistentEntityException;
import controladoresJpa.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import model.AtributoMR;
import model.DicionarioMR;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Persistence;
import model.AtributoMER;
import model.AssociacaoTabelaAtributo;

/**
 * Módulo MR
 * Classe de Entidade do Banco de Dados, gerada automaticamente, porém com certas modificações
 * @author Eduardo, Maylon e Kamilla
 */
public class AtributoMRJpaController implements Serializable {

    public AtributoMRJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;
public AtributoMRJpaController(){
    if(emf==null)
        emf = Persistence.createEntityManagerFactory("unb-gama-threedsPU");
            }
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(AtributoMR atributoMR) throws PreexistingEntityException, Exception {
        if (atributoMR.getDicionarioMRList() == null) {
            atributoMR.setDicionarioMRList(new ArrayList<DicionarioMR>());
        }
        if (atributoMR.getAtributoMERList() == null) {
            atributoMR.setAtributoMERList(new ArrayList<AtributoMER>());
        }
        if (atributoMR.getAssociacaoTabelaAtributoList() == null) {
            atributoMR.setAssociacaoTabelaAtributoList(new ArrayList<AssociacaoTabelaAtributo>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<DicionarioMR> attachedDicionarioMRList = new ArrayList<DicionarioMR>();
            for (DicionarioMR dicionarioMRListDicionarioMRToAttach : atributoMR.getDicionarioMRList()) {
                dicionarioMRListDicionarioMRToAttach = em.getReference(dicionarioMRListDicionarioMRToAttach.getClass(), dicionarioMRListDicionarioMRToAttach.getId());
                attachedDicionarioMRList.add(dicionarioMRListDicionarioMRToAttach);
            }
            atributoMR.setDicionarioMRList(attachedDicionarioMRList);
            List<AtributoMER> attachedAtributoMERList = new ArrayList<AtributoMER>();
            for (AtributoMER atributoMERListAtributoMERToAttach : atributoMR.getAtributoMERList()) {
                atributoMERListAtributoMERToAttach = em.getReference(atributoMERListAtributoMERToAttach.getClass(), atributoMERListAtributoMERToAttach.getNome());
                attachedAtributoMERList.add(atributoMERListAtributoMERToAttach);
            }
            atributoMR.setAtributoMERList(attachedAtributoMERList);
            List<AssociacaoTabelaAtributo> attachedAssociacaoTabelaAtributoList = new ArrayList<AssociacaoTabelaAtributo>();
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListAssociacaoTabelaAtributoToAttach : atributoMR.getAssociacaoTabelaAtributoList()) {
                associacaoTabelaAtributoListAssociacaoTabelaAtributoToAttach = em.getReference(associacaoTabelaAtributoListAssociacaoTabelaAtributoToAttach.getClass(), associacaoTabelaAtributoListAssociacaoTabelaAtributoToAttach.getCodigo());
                attachedAssociacaoTabelaAtributoList.add(associacaoTabelaAtributoListAssociacaoTabelaAtributoToAttach);
            }
            atributoMR.setAssociacaoTabelaAtributoList(attachedAssociacaoTabelaAtributoList);
            em.persist(atributoMR);
            for (DicionarioMR dicionarioMRListDicionarioMR : atributoMR.getDicionarioMRList()) {
                dicionarioMRListDicionarioMR.getAtributoMRList().add(atributoMR);
                dicionarioMRListDicionarioMR = em.merge(dicionarioMRListDicionarioMR);
            }
            for (AtributoMER atributoMERListAtributoMER : atributoMR.getAtributoMERList()) {
                atributoMERListAtributoMER.getAtributoMRList().add(atributoMR);
                atributoMERListAtributoMER = em.merge(atributoMERListAtributoMER);
            }
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListAssociacaoTabelaAtributo : atributoMR.getAssociacaoTabelaAtributoList()) {
                AtributoMR oldNomeatributoOfAssociacaoTabelaAtributoListAssociacaoTabelaAtributo = associacaoTabelaAtributoListAssociacaoTabelaAtributo.getNomeatributo();
                associacaoTabelaAtributoListAssociacaoTabelaAtributo.setNomeatributo(atributoMR);
                associacaoTabelaAtributoListAssociacaoTabelaAtributo = em.merge(associacaoTabelaAtributoListAssociacaoTabelaAtributo);
                if (oldNomeatributoOfAssociacaoTabelaAtributoListAssociacaoTabelaAtributo != null) {
                    oldNomeatributoOfAssociacaoTabelaAtributoListAssociacaoTabelaAtributo.getAssociacaoTabelaAtributoList().remove(associacaoTabelaAtributoListAssociacaoTabelaAtributo);
                    oldNomeatributoOfAssociacaoTabelaAtributoListAssociacaoTabelaAtributo = em.merge(oldNomeatributoOfAssociacaoTabelaAtributoListAssociacaoTabelaAtributo);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findAtributoMR(atributoMR.getNome()) != null) {
                throw new PreexistingEntityException("AtributoMR " + atributoMR + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(AtributoMR atributoMR) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            AtributoMR persistentAtributoMR = em.find(AtributoMR.class, atributoMR.getNome());
            List<DicionarioMR> dicionarioMRListOld = persistentAtributoMR.getDicionarioMRList();
            List<DicionarioMR> dicionarioMRListNew = atributoMR.getDicionarioMRList();
            List<AtributoMER> atributoMERListOld = persistentAtributoMR.getAtributoMERList();
            List<AtributoMER> atributoMERListNew = atributoMR.getAtributoMERList();
            List<AssociacaoTabelaAtributo> associacaoTabelaAtributoListOld = persistentAtributoMR.getAssociacaoTabelaAtributoList();
            List<AssociacaoTabelaAtributo> associacaoTabelaAtributoListNew = atributoMR.getAssociacaoTabelaAtributoList();
            List<String> illegalOrphanMessages = null;
            
            if( associacaoTabelaAtributoListNew !=null)
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListOldAssociacaoTabelaAtributo : associacaoTabelaAtributoListOld) {
                if (!associacaoTabelaAtributoListNew.contains(associacaoTabelaAtributoListOldAssociacaoTabelaAtributo)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain AssociacaoTabelaAtributo " + associacaoTabelaAtributoListOldAssociacaoTabelaAtributo + " since its nomeatributo field is not nullable.");
                }
            }
            
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<DicionarioMR> attachedDicionarioMRListNew = new ArrayList<DicionarioMR>();
            
            if( dicionarioMRListNew !=null)
            for (DicionarioMR dicionarioMRListNewDicionarioMRToAttach : dicionarioMRListNew) {
                dicionarioMRListNewDicionarioMRToAttach = em.getReference(dicionarioMRListNewDicionarioMRToAttach.getClass(), dicionarioMRListNewDicionarioMRToAttach.getId());
                attachedDicionarioMRListNew.add(dicionarioMRListNewDicionarioMRToAttach);
            }
            dicionarioMRListNew = attachedDicionarioMRListNew;
            atributoMR.setDicionarioMRList(dicionarioMRListNew);
            List<AtributoMER> attachedAtributoMERListNew = new ArrayList<AtributoMER>();
            
            if( atributoMERListNew !=null)
            for (AtributoMER atributoMERListNewAtributoMERToAttach : atributoMERListNew) {
                atributoMERListNewAtributoMERToAttach = em.getReference(atributoMERListNewAtributoMERToAttach.getClass(), atributoMERListNewAtributoMERToAttach.getNome());
                attachedAtributoMERListNew.add(atributoMERListNewAtributoMERToAttach);
            }
            atributoMERListNew = attachedAtributoMERListNew;
            atributoMR.setAtributoMERList(atributoMERListNew);
            List<AssociacaoTabelaAtributo> attachedAssociacaoTabelaAtributoListNew = new ArrayList<AssociacaoTabelaAtributo>();
            
            
            if( associacaoTabelaAtributoListNew !=null)
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListNewAssociacaoTabelaAtributoToAttach : associacaoTabelaAtributoListNew) {
                associacaoTabelaAtributoListNewAssociacaoTabelaAtributoToAttach = em.getReference(associacaoTabelaAtributoListNewAssociacaoTabelaAtributoToAttach.getClass(), associacaoTabelaAtributoListNewAssociacaoTabelaAtributoToAttach.getCodigo());
                attachedAssociacaoTabelaAtributoListNew.add(associacaoTabelaAtributoListNewAssociacaoTabelaAtributoToAttach);
            }
            associacaoTabelaAtributoListNew = attachedAssociacaoTabelaAtributoListNew;
            atributoMR.setAssociacaoTabelaAtributoList(associacaoTabelaAtributoListNew);
            atributoMR = em.merge(atributoMR);
            
            if( dicionarioMRListOld !=null)
            for (DicionarioMR dicionarioMRListOldDicionarioMR : dicionarioMRListOld) {
                if (!dicionarioMRListNew.contains(dicionarioMRListOldDicionarioMR)) {
                    dicionarioMRListOldDicionarioMR.getAtributoMRList().remove(atributoMR);
                    dicionarioMRListOldDicionarioMR = em.merge(dicionarioMRListOldDicionarioMR);
                }
            }
            
            if( dicionarioMRListNew !=null)
            for (DicionarioMR dicionarioMRListNewDicionarioMR : dicionarioMRListNew) {
                if (!dicionarioMRListOld.contains(dicionarioMRListNewDicionarioMR)) {
                    dicionarioMRListNewDicionarioMR.getAtributoMRList().add(atributoMR);
                    dicionarioMRListNewDicionarioMR = em.merge(dicionarioMRListNewDicionarioMR);
                }
            }
            
            if( atributoMERListOld !=null)
            for (AtributoMER atributoMERListOldAtributoMER : atributoMERListOld) {
                if (!atributoMERListNew.contains(atributoMERListOldAtributoMER)) {
                    atributoMERListOldAtributoMER.getAtributoMRList().remove(atributoMR);
                    atributoMERListOldAtributoMER = em.merge(atributoMERListOldAtributoMER);
                }
            }
            
            if( atributoMERListNew !=null)
            for (AtributoMER atributoMERListNewAtributoMER : atributoMERListNew) {
                if (!atributoMERListOld.contains(atributoMERListNewAtributoMER)) {
                    atributoMERListNewAtributoMER.getAtributoMRList().add(atributoMR);
                    atributoMERListNewAtributoMER = em.merge(atributoMERListNewAtributoMER);
                }
            }
            
            if( associacaoTabelaAtributoListNew !=null)
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListNewAssociacaoTabelaAtributo : associacaoTabelaAtributoListNew) {
                if (!associacaoTabelaAtributoListOld.contains(associacaoTabelaAtributoListNewAssociacaoTabelaAtributo)) {
                    AtributoMR oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo = associacaoTabelaAtributoListNewAssociacaoTabelaAtributo.getNomeatributo();
                    associacaoTabelaAtributoListNewAssociacaoTabelaAtributo.setNomeatributo(atributoMR);
                    associacaoTabelaAtributoListNewAssociacaoTabelaAtributo = em.merge(associacaoTabelaAtributoListNewAssociacaoTabelaAtributo);
                    if (oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo != null && !oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo.equals(atributoMR)) {
                        oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo.getAssociacaoTabelaAtributoList().remove(associacaoTabelaAtributoListNewAssociacaoTabelaAtributo);
                        oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo = em.merge(oldNomeatributoOfAssociacaoTabelaAtributoListNewAssociacaoTabelaAtributo);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = atributoMR.getNome();
                if (findAtributoMR(id) == null) {
                    throw new NonexistentEntityException("The atributoMR with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            AtributoMR atributoMR;
            try {
                atributoMR = em.getReference(AtributoMR.class, id);
                atributoMR.getNome();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The atributoMR with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<AssociacaoTabelaAtributo> associacaoTabelaAtributoListOrphanCheck = atributoMR.getAssociacaoTabelaAtributoList();
            for (AssociacaoTabelaAtributo associacaoTabelaAtributoListOrphanCheckAssociacaoTabelaAtributo : associacaoTabelaAtributoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This AtributoMR (" + atributoMR + ") cannot be destroyed since the AssociacaoTabelaAtributo " + associacaoTabelaAtributoListOrphanCheckAssociacaoTabelaAtributo + " in its associacaoTabelaAtributoList field has a non-nullable nomeatributo field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<DicionarioMR> dicionarioMRList = atributoMR.getDicionarioMRList();
            for (DicionarioMR dicionarioMRListDicionarioMR : dicionarioMRList) {
                dicionarioMRListDicionarioMR.getAtributoMRList().remove(atributoMR);
                dicionarioMRListDicionarioMR = em.merge(dicionarioMRListDicionarioMR);
            }
            List<AtributoMER> atributoMERList = atributoMR.getAtributoMERList();
            for (AtributoMER atributoMERListAtributoMER : atributoMERList) {
                atributoMERListAtributoMER.getAtributoMRList().remove(atributoMR);
                atributoMERListAtributoMER = em.merge(atributoMERListAtributoMER);
            }
            em.remove(atributoMR);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<AtributoMR> findAtributoMREntities() {
        return findAtributoMREntities(true, -1, -1);
    }

    public List<AtributoMR> findAtributoMREntities(int maxResults, int firstResult) {
        return findAtributoMREntities(false, maxResults, firstResult);
    }

    private List<AtributoMR> findAtributoMREntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(AtributoMR.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public AtributoMR findAtributoMR(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(AtributoMR.class, id);
        } finally {
            em.close();
        }
    }

    public int getAtributoMRCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<AtributoMR> rt = cq.from(AtributoMR.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
